//
// File:    progtabledelegate.cpp
// Brief:   测试程序编辑table的delegate实现文件
//
// History:
// ============================================================================
// 2010-12-16    Finux Chen <finuxchen@gmail.com>    创建
// 2011-01-20    Finux Chen <finuxchen@gmail.com>    使用core模块新接口
// 2012-02-18    Finux Chen <finuxchen@gmail.com>    加入suffix处理
//
#include <QtGui>

#include "progform.h"
#include "progtabledelegate.h"

#include "../core/aprcfg.h"

//const char *listOnOff[] = { "ON", "OFF" };

//static const char *listFilter[] = { "OFF", "ON(1)", "ON(2)", "ON(4)",
//									"ON(8)", "ON(16)" };

//
// 当range切换时,转换数据的表现形式
// NOTE!:似乎还有些问题,暂时不用,以后加入
//
static double convDataRange(double current, double upper, double lower, ushort decimals)
{
	double val = current;
	val = val > upper ? upper : val;
	val = val < lower ? lower : val;

	val *= decimals;
	int ival = (int)val;
	val = (double)ival / decimals;
	return val;
}



ProgTableDelegate::ProgTableDelegate(QObject *parent/* = 0*/)
	: QItemDelegate(parent)
{
}

QWidget *ProgTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &,
						const QModelIndex &index) const
{
	QLabel 			*label;
	QComboBox 		*combo;
	QDoubleSpinBox	*dspin;

    QStringList		filterOption;
    QStringList 	biasRanges;
    QStringList 	measRanges;
    QStringList     onOff;
	QString			range;
	QString 		itemSuffix;
	QString			item;
	double			upper;
	double			lower;
	double			step;
    ushort			decimals;
	QModelIndex		sibling;
	int				strIndex;

	switch(index.row()){
	case PROG_TABLE_ROW_NAME:
		label = new QLabel(parent);
		return label;
//	case PROG_TABLE_ROW_CHANNEL:
//		combo = new QComboBox(parent);
//		for(int i = 0; i < ProgForm::getChnCount(); ++i){
//			combo->addItem(QString::number(i+1));
//		}
//		return combo;
//	case PROG_TABLE_ROW_BIAS:
//		sibling = index.sibling(PROG_TABLE_ROW_BIAS_UNIT, index.column());
//		range = sibling.model()->data(sibling, Qt::EditRole).toString();
//        //getRangeDetailByName(range, PM_BRANGE_ATTR, upper, lower, step, decimals);
//        AprCfg::getRangeDetailByName(
//                range, PM_BRANGE_ATTR, upper, lower, step, decimals);
//
//		dspin = new QDoubleSpinBox(parent);
//		dspin->setRange(lower, upper);
//		dspin->setSingleStep(step);
//		dspin->setDecimals(decimals);
//		dspin->setAccelerated(true);
//		return dspin;
	case PROG_TABLE_ROW_BIAS_UNIT:
		sibling = index.sibling(PROG_TABLE_ROW_NAME, index.column());
		itemSuffix = sibling.model()->data(sibling, Qt::DisplayRole).toString();
	//	item = getItemName(itemSuffix);
	//	qDebug() << item;
	//	QString itemName;
		strIndex = itemSuffix.indexOf('_');
		item = itemSuffix.left(strIndex);
	//	qDebug() << item;
        //getRangesByItem(item, PM_BRANGE_ATTR, ranges);
        AprCfg::getRangesByItem(item, PM_BRANGE_ATTR, biasRanges);

		combo = new QComboBox(parent);
        combo->addItems(biasRanges);
		return combo;
	case PROG_TABLE_ROW_TIME:
//		getRangeDetailByCode(PM_T9999ms, upper, lower, step, decimals);
        AprCfg::getRangeDetailByCode(PM_T9999ms, upper, lower, step, decimals);

		dspin = new QDoubleSpinBox(parent);
		dspin->setRange(lower, upper);
		dspin->setSingleStep(step);
		dspin->setDecimals(decimals);
		dspin->setAccelerated(true);
		return dspin;
//	case PROG_TABLE_ROW_MEAS_L:
//		sibling = index.sibling(PROG_TABLE_ROW_MEAS_UNIT, index.column());
//		range = sibling.model()->data(sibling, Qt::EditRole).toString();
////		getRangeDetailByName(range, PM_MRANGE_ATTR, upper, lower, step, decimals);
//        AprCfg::getRangeDetailByName(
//                range, PM_MRANGE_ATTR, upper, lower, step, decimals);
//
//		dspin = new QDoubleSpinBox(parent);
//		dspin->setRange(lower, upper);
//		dspin->setSingleStep(step);
//		dspin->setDecimals(decimals);
//		dspin->setValue(lower);
//		dspin->setAccelerated(true);
//		return dspin;
	case PROG_TABLE_ROW_MEAS_U:
		sibling = index.sibling(PROG_TABLE_ROW_MEAS_UNIT, index.column());
		range = sibling.model()->data(sibling, Qt::EditRole).toString();
//		getRangeDetailByName(range, PM_MRANGE_ATTR, upper, lower, step, decimals);
        AprCfg::getRangeDetailByName(
                range, PM_MRANGE_ATTR, upper, lower, step, decimals);

		dspin = new QDoubleSpinBox(parent);
		dspin->setRange(lower, upper);
		dspin->setSingleStep(step);
		dspin->setDecimals(decimals);
		dspin->setValue(upper);
		dspin->setAccelerated(true);
		return dspin;
	case PROG_TABLE_ROW_MEAS_UNIT:
		sibling = index.sibling(PROG_TABLE_ROW_NAME, index.column());
		itemSuffix = sibling.model()->data(sibling, Qt::DisplayRole).toString();
		strIndex = itemSuffix.indexOf('_');
		item = itemSuffix.left(strIndex);
        //getRangesByItem(item, PM_MRANGE_ATTR, ranges);
        AprCfg::getRangesByItem(item, PM_MRANGE_ATTR, measRanges);

		combo = new QComboBox(parent);
        combo->addItems(measRanges);
		return combo;
	case PROG_TABLE_ROW_FILTER:
        //for(int i = 0; i < 6; ++i){
        //	slistFilter << listFilter[i];
        //}
        AprCfg::getNamesByAttr(PM_FIL_ATTR, filterOption);

		combo = new QComboBox(parent);
        //combo->addItems(slistFilter);
        combo->addItems(filterOption);
		return combo;
	case PROG_TABLE_ROW_LIMIT:
        //getRangeDetailByCode(PM_L9_99V, upper, lower, step, decimals);
        AprCfg::getRangeDetailByCode(PM_L9_99V, upper, lower, step, decimals);

		dspin = new QDoubleSpinBox(parent);
		dspin->setRange(lower, upper);
		dspin->setSingleStep(step);
		dspin->setDecimals(decimals);
		dspin->setValue(upper);
		dspin->setAccelerated(true);
		return dspin;
	case PROG_TABLE_ROW_JUDGE:
	case PROG_TABLE_ROW_ACTIVE:
        AprCfg::getNamesByAttr(PM_ONOFF_ATTR, onOff);

		combo = new QComboBox(parent);
        //combo->addItem(listOnOff[0]);
        //combo->addItem(listOnOff[1]);
        combo->addItems(onOff);
		return combo;
    default:
        return (QWidget *)0;
	}
}

void ProgTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
	QDoubleSpinBox	*dspin;

	switch(index.row()){
	case PROG_TABLE_ROW_NAME:
		break;
//	case PROG_TABLE_ROW_CHANNEL:
	case PROG_TABLE_ROW_BIAS_UNIT:
	case PROG_TABLE_ROW_MEAS_UNIT:
	case PROG_TABLE_ROW_FILTER:
	case PROG_TABLE_ROW_JUDGE:
	case PROG_TABLE_ROW_ACTIVE:
		break;
//	case PROG_TABLE_ROW_BIAS:
	case PROG_TABLE_ROW_TIME:
	case PROG_TABLE_ROW_MEAS_L:
	case PROG_TABLE_ROW_MEAS_U:
	case PROG_TABLE_ROW_LIMIT:
		dspin = qobject_cast<QDoubleSpinBox *>(editor);
		dspin->setValue(index.model()->data(index, Qt::EditRole).toDouble());
		break;
	default:
		break;
	}
}

void ProgTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
					const QModelIndex &index) const
{
	QComboBox		*combo;
	QDoubleSpinBox	*dspin;

	QModelIndex		sibling;
	QString			range;
	double			upper;
	double			lower;
	double			step;
    ushort			decimals;

	switch(index.row()){
	case PROG_TABLE_ROW_NAME:
		break;
//	case PROG_TABLE_ROW_CHANNEL:
	case PROG_TABLE_ROW_BIAS_UNIT:
	case PROG_TABLE_ROW_MEAS_UNIT:
	case PROG_TABLE_ROW_FILTER:
	case PROG_TABLE_ROW_JUDGE:
	case PROG_TABLE_ROW_ACTIVE:
		combo = qobject_cast<QComboBox *>(editor);
		model->setData(index, combo->currentText());
		break;
//	case PROG_TABLE_ROW_BIAS:
	case PROG_TABLE_ROW_TIME:
	case PROG_TABLE_ROW_MEAS_L:
	case PROG_TABLE_ROW_MEAS_U:
	case PROG_TABLE_ROW_LIMIT:
		dspin = qobject_cast<QDoubleSpinBox *>(editor);
        model->setData(index, dspin->value());
		break;
	default:
		break;
	}

	//
	// range改变时相应改变double spin box的范围
	//
	if(index.row() == PROG_TABLE_ROW_BIAS_UNIT){
//		range = model->data(index, Qt::EditRole).toString();
//        AprCfg::getRangeDetailByName(
//                range, PM_BRANGE_ATTR, upper, lower, step, decimals);
//
//		sibling = index.sibling(PROG_TABLE_ROW_BIAS, index.column());
//		model->setData(sibling, lower);	
/*
		double val = model->data(sibling, Qt::EditRole).toDouble();
//		val = val > upper ? upper : val;
//		val = val < lower ? lower : val;
//		model->setData(sibling, val);
		double data = convDataRange(val, upper, lower, decimals);
		model->setData(sibling, data);	
*/
	}

	if(index.row() == PROG_TABLE_ROW_MEAS_UNIT){
		range = model->data(index, Qt::EditRole).toString();
        //getRangeDetailByName(range, PM_MRANGE_ATTR, upper, lower, step, decimals);
        AprCfg::getRangeDetailByName(
                range, PM_MRANGE_ATTR, upper, lower, step, decimals);

		sibling = index.sibling(PROG_TABLE_ROW_MEAS_L, index.column());
		model->setData(sibling, lower);

		sibling = index.sibling(PROG_TABLE_ROW_MEAS_U, index.column());
		model->setData(sibling, upper);
	}
}


/*
QString ProgTableDelegate::getItemName(const QString& itemSuffix)
{
	QString itemName;
	int index = itemSuffix.indexOf('_');
	itemName = itemSuffix.left(index);

	return itemName;
}
*/
